#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef double db;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+ch-'0'; ch=getchar(); }
	return x*f;
}
const int MAXN=1e5+10,MAXM=2e5+10;
int n,m,ans[MAXN];
struct node
{
	int a,b,c,cnt,ans;
	bool operator<(const node y)const
	{
		return b==y.b?c<y.c:b<y.b;
	}
}a[MAXN],t[MAXN];
bool cmp(node a,node b)
{
	return a.a==b.a?(a.b==b.b?a.c<b.c:a.b<b.b):a.a<b.a;
}
struct BIT
{
	int num[MAXM];
	inline int lowbit(int x)
	{
		return x&-x;
	}
	void update(int o,int x)
	{
		while(o<=m)
		{
			num[o]+=x;
			o+=lowbit(o);
		}
		return;
	}
	int query(int o)
	{
		int ret=0;
		while(o)
		{
			ret+=num[o];
			o-=lowbit(o);
		}
		return ret;
	}
}T1;
void CDQ(int l,int r)
{
	if(l==r)return;
	int mid=(l+r)>>1;
	CDQ(l,mid);CDQ(mid+1,r);
	int i=l,j=mid+1,cnt=0;
	while(i<=mid||j<=r)
	{
		if(j>r||(i<=mid&&a[i].b<=a[j].b))T1.update(a[i].c,a[i].cnt),t[++cnt]=a[i++];
		else a[j].ans+=T1.query(a[j].c),t[++cnt]=a[j++];
	}
	for(int i=l;i<=mid;++i)T1.update(a[i].c,-a[i].cnt);
	for(int i=l;i<=r;++i)a[i]=t[i-l+1];
	return;
}
int main()
{
	n=read();m=read();
	for(int i=1;i<=n;++i)a[i].a=read(),a[i].b=read(),a[i].c=read();
	sort(a+1,a+1+n,cmp);
	int cnt=0;
	for(int i=1;i<=n;++i)
	{
		if(a[i].a!=a[i-1].a||a[i].b!=a[i-1].b||a[i].c!=a[i-1].c)a[++cnt]=a[i];
		++a[cnt].cnt;
	}
	CDQ(1,cnt);
	for(int i=1;i<=cnt;++i)ans[a[i].cnt+a[i].ans-1]+=a[i].cnt;
	for(int i=0;i<n;++i)printf("%d\n",ans[i]);
	return 0;
}
